package team.zero.lemon.module.sys.service;

import team.zero.lemon.common.date.UTC;
import team.zero.lemon.common.exception.CustomException;
import team.zero.lemon.common.exception.LoginException;
import team.zero.lemon.common.mapper.JsonMapper;
import team.zero.lemon.common.persistence.Page;
import team.zero.lemon.common.security.session.SessionManager;
import team.zero.lemon.common.security.session.model.Function;
import team.zero.lemon.common.security.session.model.Session;
import team.zero.lemon.common.security.utils.Digests;
import team.zero.lemon.common.service.CrudService;
import team.zero.lemon.common.utils.Encodes;
import team.zero.lemon.module.sys.dao.IFunctionDao;
import team.zero.lemon.module.sys.dao.IUserDao;
import team.zero.lemon.module.sys.dao.IUserRoleDao;
import team.zero.lemon.module.sys.dao.IUserJobOrgDao;
import team.zero.lemon.module.sys.entity.LoginResult;
import team.zero.lemon.module.sys.entity.User;
import team.zero.lemon.module.sys.entity.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.zero.lemon.module.sys.entity.UserJobOrg;

import java.util.List;

/**
 * Created by bolin on 2016/5/10.
 */
@Service
public class UserService extends CrudService<IUserDao, User> {
    public static final int HASH_INTERATIONS = 1024;
    public static final int SALT_SIZE = 8;
    @Autowired
    private IUserRoleDao userRoleDao;
    @Autowired
    private IUserJobOrgDao userJobOrgDao;
    @Autowired
    private IFunctionDao functionDao;

    public List<User> findAllUsers() {
        try {
            return dao.findAll();
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    public Page<User> findUser(User user) {
        try {
            List<User> userList = dao.findPage(user);
            user.page.setList(userList);
            return user.page;
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    @Transactional
    public int SaveUser(User user) {
        try {
            if (user.isInsert()) {
                User ruser = dao.getByLoginName(user);
                if (ruser != null) {
                    throw new CustomException("用户名已经存在！");
                }
                user.setPassword(entryptPassword(user.getPassword()));
                user.preInsert();
                return dao.insert(user);
            } else {
                user.preUpdate();
                return dao.update(user);
            }
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    public Session login(User user) throws LoginException {
        Session session = new Session();
        User result = dao.getByLoginName(user);
        if (result == null) {
            throw new LoginException("系统用户不存在");
        }
        if (validatePassword(user.getPassword(), result.getPassword())) {
            session.setLoginName(result.getLoginName());
            session.setId(result.getId());
            session.setOrgId(result.getOrgId());
            session.setNikeName(result.getNickName());
            session.setOrgName(result.getOrgName());
            session.setOrgEnName(result.getOrgEnName());

            List<Function> functions = functionDao.findByUserId(result.getId());
            if (functions == null || functions.size() == 0) {
                throw new LoginException("用户没有权限");
            }
            session.setFunctions(functions);
            String token = SessionManager.getIstance().add(session);
            session.setToken(token);
            return session;
        } else {
            throw new LoginException("密码错误");
        }
    }
    public boolean logout(String token) {
        try {
            SessionManager.getIstance().remove(token);
            return true;
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    @Transactional
    public String passwd(User user) {
        try {
            LoginResult loginResult = new LoginResult();
            User result = dao.getByLoginName(user);
            if (result == null) {
                loginResult.setStatus(1);
                loginResult.setMessage("系统用户不存在");
                return JsonMapper.toJsonString(loginResult);
            }
            if (validatePassword(user.getPassword(), result.getPassword())) {

                int i = dao.updatePassword(result.getId(), entryptPassword(user.getNewpassword()), result.getId(), UTC.date());
                loginResult.setStatus(0);
                loginResult.setMessage("验证成功！");
                return JsonMapper.toJsonString(loginResult);
            } else {
                loginResult.setStatus(2);
                loginResult.setMessage("密码错误！");
                return JsonMapper.toJsonString(loginResult);
            }
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }
    }
    public List<UserRole> findUserByRoleId(UserRole userRole) {
        try {
            return userRoleDao.findByRoleId(userRole.getRoleId());
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    public List<UserRole> findUserByUserId(UserRole userRole) {
        try {
            return userRoleDao.findByUserId(userRole.getUserId());
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }

    @Transactional
    public List<Function> findFunctionByToken(String token) {
        try {
            Session principal = (Session) SessionManager.getIstance().get(token);
            return principal.getFunctions();
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    @Transactional
    public boolean deleteAll() {
        try {
            dao.deleteAll();
            return true;
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }
    }
    @Transactional
    public int saveUserRole(List<UserRole> userRoles) {
        try {
            if(userRoles.get(0).getUserId()==null){
                userRoleDao.deleteByRoleId(userRoles.get(0).getRoleId());
            }else {
                userRoleDao.deleteByUserId(userRoles.get(0).getUserId());
            }

            for (UserRole roleFunction : userRoles) {
                roleFunction.preInsert();
            }
            return userRoleDao.insert(userRoles);

        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    @Transactional
    public int saveUserJobOrg(List<UserJobOrg> userJobOrgs) {
        try {
            userJobOrgDao.deleteByUserIdJobId(userJobOrgs.get(0).getUserId(),userJobOrgs.get(0).getJobId());
            for (UserJobOrg userRoleOrg : userJobOrgs) {
                userRoleOrg.preInsert();
            }
            return userJobOrgDao.insert(userJobOrgs);
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }

    @Transactional
    public int userRoleDelete(List<UserRole> userRoles) {
        try {
            return userRoleDao.deleteByRoleId(userRoles.get(0).getRoleId());
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    @Transactional
    public int deleteUserRoleByUserId(UserRole userRole) {
        try {
            return userRoleDao.deleteByUserId(userRole.getUserId());
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }

    @Transactional
    public int deleteUserJobOrg(List<UserJobOrg> userJobOrg) {
        try {
            return userJobOrgDao .deleteByUserIdJobId(userJobOrg.get(0).getUserId(),userJobOrg.get(0).getJobId());
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }

    public List<UserJobOrg> findUserJobOrgByUserIdJobId(UserJobOrg userRoleOrg) {
        try {
            return userJobOrgDao.findByUserIdJobId(userRoleOrg);
        } catch (Exception e) {
            throw new CustomException(e);
        }
    }
    /**
     * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
     */
    public static String entryptPassword(String plainPassword) {
        byte[] salt = Digests.generateSalt(SALT_SIZE);
        byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
        return Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);
    }
    /**
     * 验证密码
     *
     * @param plainPassword 明文密码
     * @param password      密文密码
     * @return 验证成功返回true
     */
    public static boolean validatePassword(String plainPassword, String password) {
        byte[] salt = Encodes.decodeHex(password.substring(0, 16));
        byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
        return password.equals(Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword));
    }
}
